package org.ecloud.auth.server.provider;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.oltu.oauth2.as.issuer.MD5Generator;
import org.apache.oltu.oauth2.as.issuer.OAuthIssuerImpl;
import org.apache.oltu.oauth2.as.request.OAuthAuthzRequest;
import org.apache.oltu.oauth2.as.response.OAuthASResponse;
import org.apache.oltu.oauth2.common.OAuth;
import org.apache.oltu.oauth2.common.error.OAuthError;
import org.apache.oltu.oauth2.common.exception.OAuthProblemException;
import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
import org.apache.oltu.oauth2.common.message.OAuthResponse;
import org.apache.oltu.oauth2.common.message.types.GrantType;
import org.apache.oltu.oauth2.common.message.types.ResponseType;
import org.apache.oltu.oauth2.common.utils.OAuthUtils;
import org.ecloud.auth.server.service.OAuthService;
import org.ecloud.base.i18n.LocaleMessageSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

/** 
 * auth2.0 授权控制器
 * 
 *<pre>
 * 修改数据源配置，指向client数据库，获取授权信息
 *</pre>
 *
 * <pre> 
 * project: ecloud-auth-server
 * author: eddy
 * email: xqxyxchy@126.com
 * date: 2018年4月2日-下午8:21:12
 * rights: eddy
 * </pre>
 */
@RestController
@RequestMapping("/token/")
public class AuthorizeProvider {
	
	@Autowired
	private LocaleMessageSource localeMessageSource;
	@Autowired
	private OAuthService oAuthService;
	
	/**
	 * 获取授权码，大写部分是参数
	 * 
	 *<pre>
	 * https://api.weibo.com/oauth2/authorize?
	 * 		client_id=YOUR_CLIENT_ID&
	 * 		response_type=code&
	 * 		redirect_uri=YOUR_REGISTERED_REDIRECT_URI
	 *</pre>
	 * 
	 * @return
	 */
	@RequestMapping("authorize")
	@ResponseBody
	public Object authorize(HttpServletRequest request, HttpServletResponse response) 
			throws URISyntaxException, OAuthSystemException, IOException {
		try {
            //构建OAuth 授权请求
            OAuthAuthzRequest oauthRequest = new OAuthAuthzRequest(request);
            
            //检查传入的客户端id是否正确
            if (!oAuthService.checkClientId(oauthRequest.getClientId())) {
                OAuthResponse oresponse =
                        OAuthASResponse.errorResponse(HttpServletResponse.SC_BAD_REQUEST)
                                .setError(OAuthError.TokenResponse.INVALID_CLIENT)
                                .setErrorDescription(localeMessageSource.getMessage("invalid.client"))
                                .buildJSONMessage();
                return new ResponseEntity<String>(oresponse.getBody(), HttpStatus.valueOf(oresponse.getResponseStatus()));
            }

            //生成授权码
            String authorizationCode = null;
            //responseType目前仅支持CODE，另外还有TOKEN
            String responseType = oauthRequest.getParam(OAuth.OAUTH_RESPONSE_TYPE);
            if (responseType.equals(ResponseType.CODE.toString())) {
                OAuthIssuerImpl oauthIssuerImpl = new OAuthIssuerImpl(new MD5Generator());
                authorizationCode = oauthIssuerImpl.authorizationCode();
                oAuthService.addAuthCode(authorizationCode, oauthRequest.getClientId());
            }else{
            	OAuthResponse oresponse =
                        OAuthASResponse.errorResponse(HttpServletResponse.SC_BAD_REQUEST)
                                .setError(OAuthError.TokenResponse.INVALID_REQUEST)
                                .setErrorDescription(localeMessageSource.getMessage("invalid.request", new Object[]{responseType}))
                                .buildJSONMessage();
                return new ResponseEntity<String>(oresponse.getBody(), HttpStatus.valueOf(oresponse.getResponseStatus()));
            }

            //进行OAuth响应构建
            OAuthASResponse.OAuthAuthorizationResponseBuilder builder =
                    OAuthASResponse.authorizationResponse(request, HttpServletResponse.SC_FOUND);
            // 设置授权码
            builder.setParam(GrantType.AUTHORIZATION_CODE.toString(), authorizationCode);
            //得到到客户端重定向地址
            String redirectURI = oauthRequest.getParam(OAuth.OAUTH_REDIRECT_URI);

            //构建响应
            final OAuthResponse oresponse = builder.location(redirectURI).buildQueryMessage();

            //根据OAuthResponse返回ResponseEntity响应
            HttpHeaders headers = new HttpHeaders();
            headers.setLocation(new URI(oresponse.getLocationUri()));
            return new ResponseEntity<HttpHeaders>(headers, HttpStatus.valueOf(oresponse.getResponseStatus()));
        } catch (OAuthProblemException e) {
            //出错处理
            String redirectUri = e.getRedirectUri();
            if (OAuthUtils.isEmpty(redirectUri)) {
                //告诉客户端没有传入redirectUri直接报错
                return new ResponseEntity<String>(localeMessageSource.getMessage("invalid.redirectUri"), HttpStatus.NOT_FOUND);
            }

            //返回错误消息（如?error=）
            final OAuthResponse oresponse =
                    OAuthASResponse.errorResponse(HttpServletResponse.SC_FOUND)
                            .error(e)
                            .location(redirectUri)
                            .buildQueryMessage();
            HttpHeaders headers = new HttpHeaders();
            headers.setLocation(new URI(oresponse.getLocationUri()));
            return new ResponseEntity<HttpHeaders>(headers, HttpStatus.valueOf(oresponse.getResponseStatus()));
        }
	}
	
}
